home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / bfd / libbfd.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  13KB  |  539 lines

  1. /* libbfd.c -- random BFD support routines, only used internally.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Written by Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* $Id: libbfd.c,v 1.23 1991/10/11 10:08:30 gnu Exp $ */
  22.  
  23. #include "bfd.h"
  24. #include "sysdep.h"
  25. #include "libbfd.h"
  26.  
  27. /** Dummies for targets that don't want or need to implement
  28.    certain operations */
  29.  
  30. boolean
  31. DEFUN(_bfd_dummy_new_section_hook,(ignore, ignore_newsect),
  32.       bfd *ignore AND
  33.       asection *ignore_newsect)
  34. {
  35.   return true;
  36. }
  37.  
  38. boolean
  39. DEFUN(bfd_false ,(ignore),
  40.       bfd *ignore)
  41. {
  42.   return false;
  43. }
  44.  
  45. boolean
  46. DEFUN(bfd_true,(ignore),
  47.       bfd *ignore)
  48. {
  49.   return true;
  50. }
  51.  
  52. PTR
  53. DEFUN(bfd_nullvoidptr,(ignore),
  54.       bfd *ignore)
  55. {
  56.   return (PTR)NULL;
  57. }
  58.  
  59. int 
  60. DEFUN(bfd_0,(ignore),
  61.       bfd *ignore)
  62. {
  63.   return 0;
  64. }
  65.  
  66. unsigned int 
  67. DEFUN(bfd_0u,(ignore),
  68.       bfd *ignore)
  69. {
  70.    return 0;
  71. }
  72.  
  73. void 
  74. DEFUN(bfd_void,(ignore),
  75.       bfd *ignore)
  76. {
  77. }
  78.  
  79. boolean
  80. DEFUN(_bfd_dummy_core_file_matches_executable_p,(ignore_core_bfd, ignore_exec_bfd),
  81.       bfd *ignore_core_bfd AND
  82.       bfd *ignore_exec_bfd)
  83. {
  84.   bfd_error = invalid_operation;
  85.   return false;
  86. }
  87.  
  88. /* of course you can't initialize a function to be the same as another, grr */
  89.  
  90. char *
  91. DEFUN(_bfd_dummy_core_file_failing_command,(ignore_abfd),
  92.       bfd *ignore_abfd)
  93. {
  94.   return (char *)NULL;
  95. }
  96.  
  97. int
  98. DEFUN(_bfd_dummy_core_file_failing_signal,(ignore_abfd),
  99.      bfd *ignore_abfd)
  100. {
  101.   return 0;
  102. }
  103.  
  104. bfd_target *
  105. DEFUN(_bfd_dummy_target,(ignore_abfd),
  106.      bfd *ignore_abfd)
  107. {
  108.   return 0;
  109. }
  110.  
  111. /** zalloc -- allocate and clear storage */
  112.  
  113.  
  114. #ifndef zalloc
  115. char *
  116. DEFUN(zalloc,(size),
  117.       bfd_size_type size)
  118. {
  119.   char *ptr = (char *) malloc ((int)size);
  120.  
  121.   if ((ptr != NULL) && (size != 0))
  122.    memset(ptr,0, size);
  123.  
  124.   return ptr;
  125. }
  126. #endif
  127.  
  128. /* Some IO code */
  129.  
  130.  
  131. /* Note that archive entries don't have streams; they share their parent's.
  132.    This allows someone to play with the iostream behind BFD's back.
  133.  
  134.    Also, note that the origin pointer points to the beginning of a file's
  135.    contents (0 for non-archive elements).  For archive entries this is the
  136.    first octet in the file, NOT the beginning of the archive header. */
  137.  
  138. static 
  139. int DEFUN(real_read,(where, a,b, file),
  140.           PTR where AND
  141.           int a AND
  142.           int b AND
  143.           FILE *file)
  144. {
  145.   return fread(where, a,b,file);
  146. }
  147. bfd_size_type
  148. DEFUN(bfd_read,(ptr, size, nitems, abfd),
  149.       PTR ptr AND
  150.       bfd_size_type size AND
  151.       bfd_size_type nitems AND
  152.       bfd *abfd)
  153. {
  154.   return (bfd_size_type)real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
  155. }
  156.  
  157. bfd_size_type
  158. DEFUN(bfd_write,(ptr, size, nitems, abfd),
  159.       CONST PTR ptr AND
  160.       bfd_size_type size AND
  161.       bfd_size_type nitems AND
  162.       bfd *abfd)
  163. {
  164.   return fwrite (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
  165. }
  166.  
  167. int
  168. DEFUN(bfd_seek,(abfd, position, direction),
  169.       bfd * CONST abfd AND
  170.       CONST file_ptr position AND
  171.       CONST int direction)
  172. {
  173.         /* For the time being, a BFD may not seek to it's end.  The
  174.            problem is that we don't easily have a way to recognize
  175.            the end of an element in an archive. */
  176.  
  177.         BFD_ASSERT(direction == SEEK_SET
  178.                    || direction == SEEK_CUR);
  179.         
  180.         if (direction == SEEK_SET && abfd->my_archive != NULL) 
  181.             {
  182.                     /* This is a set within an archive, so we need to
  183.                        add the base of the object within the archive */
  184.                     return(fseek(bfd_cache_lookup(abfd),
  185.                                  position + abfd->origin,
  186.                                  direction));
  187.             }
  188.         else 
  189.             {
  190.                     return(fseek(bfd_cache_lookup(abfd),  position, direction));
  191.             }   
  192. }
  193.  
  194. long
  195. DEFUN(bfd_tell,(abfd),
  196.       bfd *abfd)
  197. {
  198.         file_ptr ptr;
  199.  
  200.         ptr = ftell (bfd_cache_lookup(abfd));
  201.  
  202.         if (abfd->my_archive)
  203.             ptr -= abfd->origin;
  204.         return ptr;
  205. }
  206.  
  207. /** Make a string table */
  208.  
  209. /*>bfd.h<
  210.  Add string to table pointed to by table, at location starting with free_ptr.
  211.    resizes the table if necessary (if it's NULL, creates it, ignoring
  212.    table_length).  Updates free_ptr, table, table_length */
  213.  
  214. boolean
  215. DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
  216.       char **table AND
  217.       char *new_string AND
  218.       unsigned int *table_length AND
  219.       char **free_ptr)
  220. {
  221.   size_t string_length = strlen (new_string) + 1; /* include null here */
  222.   char *base = *table;
  223.   size_t space_length = *table_length;
  224.   unsigned int offset = (base ? *free_ptr - base : 0);
  225.  
  226.   if (base == NULL) {
  227.     /* Avoid a useless regrow if we can (but of course we still
  228.        take it next time */
  229.     space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ?
  230.                     DEFAULT_STRING_SPACE_SIZE : string_length+1);
  231.     base = zalloc (space_length);
  232.  
  233.     if (base == NULL) {
  234.       bfd_error = no_memory;
  235.       return false;
  236.     }
  237.   }
  238.  
  239.   if ((size_t)(offset + string_length) >= space_length) {
  240.     /* Make sure we will have enough space */
  241.     while ((size_t)(offset + string_length) >= space_length) 
  242.       space_length += space_length/2; /* grow by 50% */
  243.  
  244.     base = (char *) realloc (base, space_length);
  245.     if (base == NULL) {
  246.       bfd_error = no_memory;
  247.       return false;
  248.     }
  249.  
  250.   }
  251.  
  252.   memcpy (base + offset, new_string, string_length);
  253.   *table = base;
  254.   *table_length = space_length;
  255.   *free_ptr = base + offset + string_length;
  256.   
  257.   return true;
  258. }
  259.  
  260. /** The do-it-yourself (byte) sex-change kit */
  261.  
  262. /* The middle letter e.g. get<b>short indicates Big or Little endian
  263.    target machine.  It doesn't matter what the byte order of the host
  264.    machine is; these routines work for either.  */
  265.  
  266. /* FIXME: Should these take a count argument?
  267.    Answer (gnu@cygnus.com):  No, but perhaps they should be inline
  268.                              functions in swap.h #ifdef __GNUC__. 
  269.                              Gprof them later and find out.  */
  270.  
  271. /*proto*
  272. *i bfd_put_size
  273. *i bfd_get_size
  274. These macros as used for reading and writing raw data in sections;
  275. each access (except for bytes) is vectored through the target format
  276. of the BFD and mangled accordingly. The mangling performs any
  277. necessary endian translations and removes alignment restrictions.
  278. *+
  279. #define bfd_put_8(abfd, val, ptr) \
  280.                 (*((char *)ptr) = (char)val)
  281. #define bfd_get_8(abfd, ptr) \
  282.                 (*((char *)ptr))
  283. #define bfd_put_16(abfd, val, ptr) \
  284.                 BFD_SEND(abfd, bfd_putx16, (val,ptr))
  285. #define bfd_get_16(abfd, ptr) \
  286.                 BFD_SEND(abfd, bfd_getx16, (ptr))
  287. #define bfd_put_32(abfd, val, ptr) \
  288.                 BFD_SEND(abfd, bfd_putx32, (val,ptr))
  289. #define bfd_get_32(abfd, ptr) \
  290.                 BFD_SEND(abfd, bfd_getx32, (ptr))
  291. #define bfd_put_64(abfd, val, ptr) \
  292.                 BFD_SEND(abfd, bfd_putx64, (val, ptr))
  293. #define bfd_get_64(abfd, ptr) \
  294.                 BFD_SEND(abfd, bfd_getx64, (ptr))
  295. *-
  296. *-*/ 
  297.  
  298. /*proto*
  299. *i bfd_h_put_size
  300. *i bfd_h_get_size
  301. These macros have the same function as their @code{bfd_get_x}
  302. bretherin, except that they are used for removing information for the
  303. header records of object files. Believe it or not, some object files
  304. keep their header records in big endian order, and their data in little
  305. endan order.
  306. *+
  307. #define bfd_h_put_8(abfd, val, ptr) \
  308.                 (*((char *)ptr) = (char)val)
  309. #define bfd_h_get_8(abfd, ptr) \
  310.                 (*((char *)ptr))
  311. #define bfd_h_put_16(abfd, val, ptr) \
  312.                 BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
  313. #define bfd_h_get_16(abfd, ptr) \
  314.                 BFD_SEND(abfd, bfd_h_getx16,(ptr))
  315. #define bfd_h_put_32(abfd, val, ptr) \
  316.                 BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
  317. #define bfd_h_get_32(abfd, ptr) \
  318.                 BFD_SEND(abfd, bfd_h_getx32,(ptr))
  319. #define bfd_h_put_64(abfd, val, ptr) \
  320.                 BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
  321. #define bfd_h_get_64(abfd, ptr) \
  322.                 BFD_SEND(abfd, bfd_h_getx64,(ptr))
  323. *-
  324. *-*/ 
  325.  
  326. bfd_vma
  327. DEFUN(_do_getb16,(addr),
  328.       register bfd_byte *addr)
  329. {
  330.         return (addr[0] << 8) | addr[1];
  331. }
  332.  
  333. bfd_vma
  334. DEFUN(_do_getl16,(addr),
  335.       register bfd_byte *addr)
  336. {
  337.         return (addr[1] << 8) | addr[0];
  338. }
  339.  
  340. void
  341. DEFUN(_do_putb16,(data, addr),
  342.       bfd_vma data AND
  343.       register bfd_byte *addr)
  344. {
  345.         addr[0] = (bfd_byte)(data >> 8);
  346.         addr[1] = (bfd_byte )data;
  347. }
  348.  
  349. void
  350. DEFUN(_do_putl16,(data, addr),
  351.       bfd_vma data AND              
  352.       register bfd_byte *addr)
  353. {
  354.         addr[0] = (bfd_byte )data;
  355.         addr[1] = (bfd_byte)(data >> 8);
  356. }
  357.  
  358. bfd_vma
  359. DEFUN(_do_getb32,(addr),
  360.       register bfd_byte *addr)
  361. {
  362.         return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3];
  363. }
  364.  
  365. bfd_vma
  366. _do_getl32 (addr)
  367.         register bfd_byte *addr;
  368. {
  369.         return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0];
  370. }
  371.  
  372. bfd_vma
  373. DEFUN(_do_getb64,(addr),
  374.       register bfd_byte *addr)
  375. {
  376. #ifdef HOST_64_BIT
  377.   bfd_64_type low, high;
  378.  
  379.   high= ((((((((addr[0]) << 8) |
  380.               addr[1]) << 8) |
  381.             addr[2]) << 8) |
  382.           addr[3]) );
  383.  
  384.   low = ((((((((addr[4]) << 8) |
  385.               addr[5]) << 8) |
  386.             addr[6]) << 8) |
  387.           addr[7]));
  388.  
  389.   return high << 32 | low;
  390. #else
  391.   BFD_FAIL();
  392.   return 0;
  393. #endif
  394.  
  395. }
  396.  
  397. bfd_vma
  398. DEFUN(_do_getl64,(addr),
  399.       register bfd_byte *addr)
  400. {
  401.  
  402. #ifdef HOST_64_BIT
  403.   bfd_64_type low, high;
  404.   high= (((((((addr[7] << 8) |
  405.               addr[6]) << 8) |
  406.             addr[5]) << 8) |
  407.           addr[4]));
  408.  
  409.   low = (((((((addr[3] << 8) |
  410.               addr[2]) << 8) |
  411.             addr[1]) << 8) |
  412.           addr[0]) );
  413.  
  414.   return high << 32 | low;
  415. #else
  416.   BFD_FAIL();
  417.   return 0;
  418. #endif
  419.  
  420. }
  421.  
  422. void
  423. DEFUN(_do_putb32,(data, addr),
  424.       bfd_vma data AND
  425.       register bfd_byte *addr)
  426. {
  427.         addr[0] = (bfd_byte)(data >> 24);
  428.         addr[1] = (bfd_byte)(data >> 16);
  429.         addr[2] = (bfd_byte)(data >>  8);
  430.         addr[3] = (bfd_byte)data;
  431. }
  432.  
  433. void
  434. DEFUN(_do_putl32,(data, addr),
  435.       bfd_vma data AND
  436.       register bfd_byte *addr)
  437. {
  438.         addr[0] = (bfd_byte)data;
  439.         addr[1] = (bfd_byte)(data >>  8);
  440.         addr[2] = (bfd_byte)(data >> 16);
  441.         addr[3] = (bfd_byte)(data >> 24);
  442. }
  443. void
  444. DEFUN(_do_putb64,(data, addr),
  445.         bfd_vma data AND
  446.         register bfd_byte *addr)
  447. {
  448. #ifdef HOST_64_BIT
  449.   addr[0] = (bfd_byte)(data >> (7*8));
  450.   addr[1] = (bfd_byte)(data >> (6*8));
  451.   addr[2] = (bfd_byte)(data >> (5*8));
  452.   addr[3] = (bfd_byte)(data >> (4*8));
  453.   addr[4] = (bfd_byte)(data >> (3*8));
  454.   addr[5] = (bfd_byte)(data >> (2*8));
  455.   addr[6] = (bfd_byte)(data >> (1*8));
  456.   addr[7] = (bfd_byte)(data >> (0*8));
  457. #else
  458.   BFD_FAIL();
  459. #endif
  460.  
  461. }
  462.  
  463. void
  464. DEFUN(_do_putl64,(data, addr),
  465.       bfd_vma data AND
  466.       register bfd_byte *addr)
  467. {
  468. #ifdef HOST_64_BIT
  469.   addr[7] = (bfd_byte)(data >> (7*8));
  470.   addr[6] = (bfd_byte)(data >> (6*8));
  471.   addr[5] = (bfd_byte)(data >> (5*8));
  472.   addr[4] = (bfd_byte)(data >> (4*8));
  473.   addr[3] = (bfd_byte)(data >> (3*8));
  474.   addr[2] = (bfd_byte)(data >> (2*8));
  475.   addr[1] = (bfd_byte)(data >> (1*8));
  476.   addr[0] = (bfd_byte)(data >> (0*8));
  477. #else
  478.   BFD_FAIL();
  479. #endif
  480.  
  481. }
  482.  
  483.  
  484. /* Default implementation */
  485.  
  486. boolean
  487. DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count),
  488.       bfd *abfd AND
  489.       sec_ptr section AND
  490.       PTR location AND
  491.       file_ptr offset AND
  492.       bfd_size_type count)
  493. {
  494.     if (count == 0)
  495.         return true;
  496.     if ((bfd_size_type)(offset+count) > section->size
  497.         || bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1
  498.         || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
  499.         return (false); /* on error */
  500.     return (true);
  501. }
  502.  
  503. /* This generic function can only be used in implementations where creating
  504.    NEW sections is disallowed.  It is useful in patching existing sections
  505.    in read-write files, though.  See other set_section_contents functions
  506.    to see why it doesn't work for new sections.  */
  507. boolean
  508. DEFUN(bfd_generic_set_section_contents, (abfd, section, location, offset, count),
  509.       bfd *abfd AND
  510.       sec_ptr section AND
  511.       PTR location AND
  512.       file_ptr offset AND
  513.       bfd_size_type count)
  514. {
  515.     if (count == 0)
  516.         return true;
  517.     if ((bfd_size_type)(offset+count) > section->size
  518.         || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
  519.         || bfd_write(location, (bfd_size_type)1, count, abfd) != count)
  520.         return (false); /* on error */
  521.     return (true);
  522. }
  523.  
  524. /*proto-internal*
  525. *i bfd_log2
  526. Return the log base 2 of the value supplied, rounded up. eg an arg
  527. of 1025 would return 11.
  528. *; PROTO(bfd_vma, bfd_log2,(bfd_vma x));
  529. *-*/
  530.  
  531. bfd_vma bfd_log2(x)
  532. bfd_vma x;
  533. {
  534.   bfd_vma  result = 0;
  535.   while ( (bfd_vma)(1<< result) < x)
  536.     result++;
  537.   return result;
  538. }
  539.